prevent buffer overflow in directDMARead#2004
Conversation
📝 WalkthroughWalkthroughModified the Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/core/gpu.cc (1)
697-701: Harden transfer accounting against FIFO/request mismatch.At Line 699,
transferSizeis reduced by the full pre-read FIFO size, not by the actual requested read length. If FIFO words ever exceed the request,transferSizecan become negative before Line 701. Consider clamping consumed words and looping whiletransferSize > 0.Suggested hardening patch
void PCSX::GPU::directDMARead(uint32_t *dest, int transferSize, uint32_t hwAddr) { auto size = m_readFifo->size(); - m_readFifo->read(dest, transferSize * 4); - transferSize -= size / 4; - dest += size / 4; - while (transferSize != 0) { + int wordsRead = static_cast<int>(size / 4); + if (wordsRead > transferSize) wordsRead = transferSize; + m_readFifo->read(dest, wordsRead * 4); + transferSize -= wordsRead; + dest += wordsRead; + while (transferSize > 0) { *dest++ = m_dataRet; transferSize--; } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/core/gpu.cc` around lines 697 - 701, The current loop subtracts the entire pre-read FIFO word count (size/4) from transferSize which can make transferSize negative if the FIFO contains more words than requested; update the logic around m_readFifo->read(dest, ...) in function(s) using m_readFifo, transferSize and dest to clamp the consumed word count to the actual requested amount: compute consumed = std::min(static_cast<size_t>(transferSize), size / 4), call m_readFifo->read(dest, consumed * 4), decrement transferSize by consumed, advance dest by consumed, and iterate while (transferSize > 0) so you never subtract more than requested and never produce a negative transferSize.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/core/gpu.cc`:
- Around line 697-701: The current loop subtracts the entire pre-read FIFO word
count (size/4) from transferSize which can make transferSize negative if the
FIFO contains more words than requested; update the logic around
m_readFifo->read(dest, ...) in function(s) using m_readFifo, transferSize and
dest to clamp the consumed word count to the actual requested amount: compute
consumed = std::min(static_cast<size_t>(transferSize), size / 4), call
m_readFifo->read(dest, consumed * 4), decrement transferSize by consumed,
advance dest by consumed, and iterate while (transferSize > 0) so you never
subtract more than requested and never produce a negative transferSize.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 94b00142-175e-4889-abcc-49af674fa71f
📒 Files selected for processing (1)
src/core/gpu.cc
In the directDMARead function, when the requested transferSize exceeds the available data in m_readFifo, the code attempts to pad the remainder of the destination buffer with m_dataRet.
Due to a missing transferSize-- operation within the while loop, the dest pointer continues to increment indefinitely (or until a segmentation fault occurs), causing a heap buffer overflow.
This fix resolves the crash observed when running the original Japanese version of Planet Laika, which triggers this specific DMA padding scenario.